/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.felipescl.asymmetricgridview.app.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.PopupDialog;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;

import com.felipecsl.asymmetricgridview.AgvRecyclerViewAdapter;
import com.felipecsl.asymmetricgridview.AsymmetricItem;
import com.felipecsl.asymmetricgridview.AsymmetricRecyclerView;
import com.felipecsl.asymmetricgridview.AsymmetricRecyclerViewAdapter;
import com.felipecsl.asymmetricgridview.BaseViewHolder;
import com.felipecsl.asymmetricgridview.LogUtil;
import com.felipecsl.asymmetricgridview.ResourceTable;
import com.felipecsl.asymmetricgridview.Utils;
import com.felipescl.asymmetricgridview.app.DemoItem;
import com.felipescl.asymmetricgridview.app.DemoUtils;
import com.felipescl.asymmetricgridview.app.ElementHelper;

import java.util.List;

/**
 * 主界面
 *
 * @since 2021-04-02
 */
public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
    private final DemoUtils demoUtils = new DemoUtils();
    private final int count = 50;
    private final int column = 3;
    private final int spacing = 3;
    private final int componentType = 2;
    private AsymmetricRecyclerView recyclerView;
    private RecyclerViewAdapter adapter;
    private PopupDialog dialog;
    private final int one = 1;
    private final int two = 2;
    private final int three = 3;
    private final int four = 4;
    private final int five = 5;
    private final int sixten = 16;
    private final int twenty = 20;
    private final int seventy = 70;
    private final int fifty = 50;
    private final int small = 120;
    private final int big = 240;
    private final int thousand = 1000;
    private final int openDuration = 350;
    private final int closeDuration = 290;
    private final int closeY = -220;
    private int currentId = ResourceTable.Id_grid_view;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        Text title = (Text) findComponentById(ResourceTable.Id_t_title);
        Component more = findComponentById(ResourceTable.Id_tv_more);
        Component drawer = findComponentById(ResourceTable.Id_dl_drawer);
        more.setClickedListener(component -> {
            showMoreDialog();
        });
        findComponentById(ResourceTable.Id_grid_view).setClickedListener(component -> {
            if (currentId != component.getId()) {
                currentId = component.getId();
            }
            drawerClose(drawer);
            more.setVisibility(Component.VISIBLE);
            title.setText("ListView sample");
            resetItems();
        });
        findComponentById(ResourceTable.Id_recycler_view).setClickedListener(component -> {
            if (currentId != component.getId()) {
                currentId = component.getId();
            }
            drawerClose(drawer);
            more.setVisibility(Component.INVISIBLE);
            title.setText("RecyclerView sample");
            resetItems();
        });
        LogUtil.info("column ", "column : " + column);
        recyclerView = (AsymmetricRecyclerView) findComponentById(ResourceTable.Id_recyclerView);
        adapter = new RecyclerViewAdapter(demoUtils.moarItems(count));
        recyclerView.setRequestedColumnCount(column);
        recyclerView.setRequestedHorizontalSpacing(Utils.vpToPx(this, spacing));
        recyclerView.setItemProvider(new AsymmetricRecyclerViewAdapter<>(this, recyclerView, adapter));
        recyclerView.setDebugging(true);
        findComponentById(ResourceTable.Id_v_menu).setClickedListener(component -> {
            drawer.setVisibility(Component.VISIBLE);
            findComponentById(ResourceTable.Id_c_out).setVisibility(Component.VISIBLE);
            AnimatorProperty animator = new AnimatorProperty(drawer);
            animator.moveToX(Utils.vpToPx(getContext(), 0));
            animator.setDuration(openDuration);
            animator.start();
        });
        drawer.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                drawerClose(drawer);
            }
        });
    }

    private void drawerClose(Component drawer) {
        findComponentById(ResourceTable.Id_c_out).setVisibility(Component.HIDE);
        AnimatorProperty animator = new AnimatorProperty(drawer);
        animator.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
            }

            @Override
            public void onStop(Animator animator) {
            }

            @Override
            public void onCancel(Animator animator) {
            }

            @Override
            public void onEnd(Animator animator) {
                drawer.setVisibility(Component.HIDE);
                LogUtil.info("recyclerView", "  width " + recyclerView.getWidth());
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });
        animator.moveToX(Utils.vpToPx(getContext(), closeY));
        animator.setDuration(closeDuration);
        animator.start();
    }

    private void showMoreDialog() {
        Component component = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_dialog, null, false);
        dialog = new PopupDialog(getContext(), null);
        component.findComponentById(ResourceTable.Id_root).setClickedListener(component1 -> dialog.destroy());
        component.findComponentById(ResourceTable.Id_tv_1).setClickedListener(this);
        component.findComponentById(ResourceTable.Id_tv_2).setClickedListener(this);
        component.findComponentById(ResourceTable.Id_tv_3).setClickedListener(this);
        component.findComponentById(ResourceTable.Id_tv_4).setClickedListener(this);
        component.findComponentById(ResourceTable.Id_tv_5).setClickedListener(this);
        component.findComponentById(ResourceTable.Id_tv_6).setClickedListener(this);
        component.findComponentById(ResourceTable.Id_tv_7).setClickedListener(this);
        component.findComponentById(ResourceTable.Id_tv_8).setClickedListener(this);
        component.findComponentById(ResourceTable.Id_tv_9).setClickedListener(this);
        Text allReorder = (Text) component.findComponentById(ResourceTable.Id_tv_10);
        allReorder.setText(recyclerView.isAllowReordering() ? "Prevent reordering" : "Allow reordering");
        component.findComponentById(ResourceTable.Id_tv_10).setClickedListener(this);
        Text debug = (Text) component.findComponentById(ResourceTable.Id_tv_11);
        debug.setText(recyclerView.isDebugging() ? "Disable debugging" : "Enable debugging");
        component.findComponentById(ResourceTable.Id_tv_11).setClickedListener(this);
        dialog.setCustomComponent(component);
        dialog.setAutoClosable(true);
        dialog.setTransparent(true);
        dialog.setSize(DirectionalLayout.LayoutConfig.MATCH_PARENT, DirectionalLayout.LayoutConfig.MATCH_PARENT);
        dialog.setBackColor(ElementHelper.getColor(getContext(), ResourceTable.Color_dialog_background));
        dialog.show();
    }

    private AsymmetricRecyclerViewAdapter getNewAdapter() {
        return new AsymmetricRecyclerViewAdapter<>(this, recyclerView, adapter);
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_tv_1: {
                setColumn(one);
                break;
            }
            case ResourceTable.Id_tv_2: {
                setColumn(two);
                break;
            }
            case ResourceTable.Id_tv_3: {
                setColumn(three);
                break;
            }
            case ResourceTable.Id_tv_4: {
                setColumn(four);
                break;
            }
            case ResourceTable.Id_tv_5: {
                setColumn(five);
                break;
            }
            case ResourceTable.Id_tv_6: {
                setColumnWidth(small);
                break;
            }
            case ResourceTable.Id_tv_7: {
                setColumnWidth(big);
                break;
            }
            case ResourceTable.Id_tv_8: {
                appendItems();
                break;
            }
            case ResourceTable.Id_tv_9: {
                resetItems();
                break;
            }
            case ResourceTable.Id_tv_10: {
                reorder((Text) component);
                break;
            }
            case ResourceTable.Id_tv_11: {
                debug((Text) component);
                break;
            }
            default:
        }
        dialog.destroy();
    }

    private void reorder(Text component) {
        recyclerView.setAllowReordering(!recyclerView.isAllowReordering());
        component.setText(recyclerView.isAllowReordering() ? "Prevent reordering" : "Allow reordering");
    }

    private void appendItems() {
        adapter.appendItems(demoUtils.moarItems(fifty));
        recyclerView.setRequestedColumnCount(1);
    }

    private void resetItems() {
        demoUtils.setCurrentOffset(0);
        adapter.setItems(demoUtils.moarItems(fifty));
        recyclerView.setRequestedColumnCount(1);
    }

    private void debug(Text component) {
        recyclerView.setDebugging(!recyclerView.isDebugging());
        component.setText(recyclerView.isDebugging() ? "Disable debugging" : "Enable debugging");
        recyclerView.setItemProvider(getNewAdapter());
        int index = recyclerView.getFirstVisibleItemPosition();
        Component child = recyclerView.getComponentAt(0);
        int top = (child == null) ? 0 : child.getTop();
        recyclerView.scrollTo(index, top);
    }

    private void setColumn(int column) {
        recyclerView.setRequestedColumnCount(column);
        recyclerView.determineColumns();
        recyclerView.setItemProvider(getNewAdapter());
    }

    private void setColumnWidth(int columnWidth) {
        recyclerView.setRequestedColumnWidth(Utils.vpToPx(this, columnWidth));
        recyclerView.determineColumns();
        recyclerView.setItemProvider(getNewAdapter());
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    /**
     * 匹配器
     *
     * @since 2021-01-12
     */
    class RecyclerViewAdapter extends AgvRecyclerViewAdapter<ViewHolder> {
        private List<DemoItem> items;

        RecyclerViewAdapter(List<DemoItem> items) {
            this.items = items;
        }

        /**
         * 追加数据
         *
         * @param list
         */
        public void appendItems(List<DemoItem> list) {
            items.addAll(list);
            notifyDataChanged();
        }

        /**
         * 追加数据
         *
         * @param list
         */
        public void setItems(List<DemoItem> list) {
            items = list;
            notifyDataChanged();
        }

        @Override
        public ViewHolder onCreateViewHolder(ComponentContainer parent, int viewType) {
            LogUtil.info("onCreateViewHolder", "viewType    " + viewType);
            return new ViewHolder(getContext(), viewType);
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            LogUtil.info("onCreateViewHolder", "viewType    " + items.get(position).toString());
            holder.bind(items.get(position));
            holder.textView.setClickedListener(component -> {
                if (currentId == ResourceTable.Id_grid_view) {
                    ToastDialog toastDialog = new ToastDialog(MainAbilitySlice.this);
                    toastDialog.setTransparent(true);
                    Text text = new Text(getContext());
                    DirectionalLayout layout = new DirectionalLayout(getContext());
                    layout.setLayoutConfig(new ComponentContainer.LayoutConfig(
                        ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_PARENT));
                    text.setTextAlignment(TextAlignment.CENTER);
                    text.setHeight(Utils.vpToPx(getContext(), fifty));
                    text.setMinWidth(Utils.vpToPx(getContext(), small));
                    ShapeElement drawableFrame = new ShapeElement(getContext(), ResourceTable.Graphic_dialog);
                    text.setBackground(drawableFrame);
                    text.setTextSize(Utils.vpToPx(getContext(), sixten));
                    text.setMarginBottom(Utils.vpToPx(getContext(), seventy));
                    text.setText("Item " + position + " clicked");
                    text.setPaddingLeft(Utils.vpToPx(getContext(), twenty));
                    text.setPaddingRight(Utils.vpToPx(getContext(), twenty));
                    toastDialog.setComponent(text);
                    toastDialog.setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT,
                        DirectionalLayout.LayoutConfig.MATCH_CONTENT);
                    toastDialog.setDuration(thousand).show();
                }
            });
        }

        @Override
        public int getCount() {
            return items.size();
        }

        @Override
        public AsymmetricItem getItem(int position) {
            return items.get(position);
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public int getItemComponentType(int position) {
            return position % componentType == 0 ? 1 : 0;
        }
    }

    /**
     * 匹配器
     *
     * @since 2021-01-12
     */
    class ViewHolder extends BaseViewHolder {
        private final Button textView;

        ViewHolder(Context context, int viewType) {
            super(LayoutScatter.getInstance(context).parse(viewType == 0 ? ResourceTable.Layout_adapter_item
                : ResourceTable.Layout_adapter_item_odd, null, false));
            if (viewType == 0) {
                textView = (Button) getComponent().findComponentById(ResourceTable.Id_textview);
            } else {
                textView = (Button) getComponent().findComponentById(ResourceTable.Id_textview_odd);
            }
        }

        void bind(DemoItem item) {
            textView.setText(String.valueOf(item.getPosition()));
        }
    }
}
